package emergency;

import java.util.ArrayList;

import unit.Ambulance;
import unit.FireTruck;
import unit.PoliceCar;
import unit.Unit;

public class RequirementsDisaster extends RequirementsEmergency {

	/**
	 * Checks if this requirement is the right one to handle the given emergency
	 * 
	 * @param emergency
	 *            the emergency to check if this Requirement needs to handle it
	 * 
	 * @return Returns true if this is the right requirement for the given
	 *         emergency, false if not
	 */
	@Override
	boolean canHandleEmergency(Emergency emergency) {
		return (emergency instanceof Disaster);
	}

	/**
	 * Method that will create the suggestion for the given emergency, with the
	 * given units
	 * 
	 * @param emergency
	 *            the emergency we need to compute the suggestion for
	 * 
	 * @param units
	 *            list of units of which the needed units will be picked
	 * 
	 * @return Returns a list of suggested units to assign to the emergency
	 * 
	 * @throws IllegalArgumentException
	 *             not enough units are available in the given unit list
	 */
	@Override
	ArrayList<Unit> createSuggestion(Emergency emergency, ArrayList<Unit> units) {
		if (canHandleEmergency(emergency)) {
			setRequirements(emergency);
			ArrayList<Unit> suggestedUnits = new ArrayList<Unit>();

			Disaster disaster = (Disaster) emergency;

			ArrayList<Emergency> emergencies = disaster.getEmergenciesClone();

			Fire.Size maxFireSize = Fire.Size.LOCAL;

			for (Emergency e : emergencies) {
				if (e instanceof Fire) {
					Fire fire = (Fire) e;
					if (fire.getSize().equals(Fire.Size.HOUSE)
							&& maxFireSize.equals(Fire.Size.LOCAL)) {
						maxFireSize = Fire.Size.HOUSE;
					}
					if (fire.getSize().equals(Fire.Size.FACILITY)) {
						maxFireSize = Fire.Size.FACILITY;
					}
				}
			}

			int amb = getTotalAmbulancesNeeded();
			int pol = getTotalPoliceCarsNeeded();
			int fir = getTotalFireTrucksNeeded();

			for (Unit u : units) {
				if (u instanceof FireTruck) {
					FireTruck fireTruck = (FireTruck) u;
					if (fir > 0
							&& fireTruck.getMaxFireSize().equals(maxFireSize)) {
						suggestedUnits.add(fireTruck);
						fir--;
					}
				}
				if (u instanceof PoliceCar) {
					if (pol > 0) {
						suggestedUnits.add(u);
						pol--;
					}
				}
				if (u instanceof Ambulance) {
					if (amb > 0) {
						suggestedUnits.add(u);
						amb--;
					}
				}
			}

			emergency.setEmergencyRequirements(this);
			if (amb == 0 && fir == 0 && pol == 0)

				return suggestedUnits;

			else
				throw new IllegalArgumentException(
						"Not enough units given to handle this emergency");
		} else {
			return getNextInChain().createSuggestion(emergency, units);
		}
	}

	/**
	 * Method for setting the total units needed, depending on this requirement
	 * 
	 * @post The total amount of ambulances needed is set, depending on this
	 *       requirement
	 * 
	 * @post The total amount of policecars needed is set, depending on this
	 *       requirement
	 * 
	 * @post The total amount of firetrucks needed is set, depending on this
	 *       requirement
	 * 
	 * @post The total amount of units needed is set, depending on this
	 *       requirement
	 */
	@Override
	void setRequirements(Emergency emergency) {
		if (canHandleEmergency(emergency)) {
			emergency.setEmergencyRequirements(this);
			setTotalAmbulancesNeeded(0);
			setTotalFireTrucksNeeded(0);
			setTotalPoliceCarsNeeded(0);
			setTotalUnitsNeeded(0);

			Disaster disaster = (Disaster) emergency;

			ArrayList<Emergency> emergencies = disaster.getEmergenciesClone();

			@SuppressWarnings("unused")
			Fire.Size maxFireSize = Fire.Size.LOCAL;

			for (Emergency e : emergencies) {
				
				e.getRequirementsEmergency().setRequirements(e);
				if (e.getSeverity().equals(Severity.SERIOUS)
						|| e.getSeverity().equals(Severity.URGENT)) {
					setTotalAmbulancesNeeded(getTotalAmbulancesNeeded()
							+ e.getRequirementsEmergency()
									.getTotalAmbulancesNeeded());
					setTotalFireTrucksNeeded(getTotalFireTrucksNeeded()
							+ e.getRequirementsEmergency()
									.getTotalFireTrucksNeeded());
					setTotalPoliceCarsNeeded(getTotalPoliceCarsNeeded()
							+ e.getRequirementsEmergency()
									.getTotalPoliceCarsNeeded());
				} else {
					if (e.getTotalAmbulancesNeeded() > this
							.getTotalAmbulancesNeeded())
						setTotalAmbulancesNeeded(getTotalAmbulancesNeeded()
								+ (e.getTotalAmbulancesNeeded() - this
										.getTotalAmbulancesNeeded()));
					if (e.getTotalFireTrucksNeeded() > this
							.getTotalFireTrucksNeeded())
						setTotalFireTrucksNeeded(getTotalFireTrucksNeeded()
								+ (e.getTotalFireTrucksNeeded() - this
										.getTotalFireTrucksNeeded()));
					if (e.getTotalPoliceCarsNeeded() > this
							.getTotalFireTrucksNeeded())
						setTotalPoliceCarsNeeded(getTotalPoliceCarsNeeded()
								+ (e.getTotalPoliceCarsNeeded() - this
										.getTotalPoliceCarsNeeded()));
				}
			}
			setTotalUnitsNeeded(getTotalAmbulancesNeeded()
					+ getTotalFireTrucksNeeded() + getTotalPoliceCarsNeeded());
		} else
			getNextInChain().setRequirements(emergency);
	}

}
